/*
 * Copyright (c) 2010-2020 DMGIS Ltd. All Rights Reserved.
 *
 * This software is the confidential and proprietary information of
 * DMGIS. You shall not disclose such Confidential Information
 * and shall use it only in accordance with the terms of the agreements
 * you entered into with DMGIS.
 *
 */
package com.dmgis.qxfw.dataservice.businessservice.yyrb.controller;

import com.dmgis.entity.DmMapPoint;
import com.dmgis.entity.DmMapRectangle;
import com.dmgis.qxfw.dataservice.businessservice.api.domain.DbConfig;
import com.dmgis.qxfw.dataservice.businessservice.common.domain.CEntity;
import com.dmgis.qxfw.dataservice.businessservice.common.domain.LogQuery;
import com.dmgis.qxfw.dataservice.businessservice.common.domain.MyPoint;
import com.dmgis.qxfw.dataservice.businessservice.common.entity.LogWarning;
import com.dmgis.qxfw.dataservice.businessservice.common.entity.WaterLoggingSet;
import com.dmgis.qxfw.dataservice.businessservice.common.util.DateTime;
import com.dmgis.qxfw.dataservice.businessservice.common.util.FileUtil;
import com.dmgis.qxfw.dataservice.businessservice.dmgis_mongodb_srv.dataservice.service.Impl.FileRequestService;
import com.dmgis.qxfw.dataservice.businessservice.dmgis_mongodb_srv.dataservice.service.Impl.MongoService1;
import com.dmgis.qxfw.dataservice.businessservice.yyrb.service.IWarnService;
import com.dmgis.qxfw.dataservice.gisservice.service.ITransformService;
import com.dmgis.qxfw.dataservice.gisservice.service.Transform;
import com.dmgis.weblib.MapCommon;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.*;


/**
 * This class is used for 预警查询类
 *
 * @author dsq
 * @version 1.0, 2018年7月18日 下午3:33:27
 */
@Controller
@RequestMapping("/xtrb")
public class Warning {
	private  final String operatingSystem;

	@Autowired
	public Warning(String operatingSystem) {
		this.operatingSystem = operatingSystem;
	}
	@Resource
    IWarnService warnQueryService;

	@Resource
	private ITransformService transformService;

	@Resource
	private Transform transform;
//	MongoService1 ms = new MongoService1();

	FileRequestService ms = new FileRequestService();



	/**
	 * 初始化登录界面
	 * @return
	 */
	@RequestMapping("/initLogPage")
	@ResponseBody
	public Object initLogQueryPage() {
		ArrayList<String> result = new ArrayList<String>();
		DateTime endDate = new DateTime(warnQueryService.getLogNewDate());
		result.add(endDate.AddDays(-7).toDateString());
		result.add(endDate.toDateString());
		return result;
	}

	/**
	 * 获取地灾预警信息
	 *
	 * @param request
	 * @param model
	 * @return
	 * @author dsq
	 * @throws Exception
	 * @date 2018年7月10日
	 */
	@RequestMapping("/getDZLogInfo")
	@ResponseBody
	public Object getLogInfo(HttpServletRequest request, Model model) throws Exception {
        String startDate = request.getParameter("startDate");
        String endDate = request.getParameter("endDate");
        LogQuery logQuery = new LogQuery();
        logQuery.setStartDate(startDate + " 00:00:00");
        logQuery.setEndDate(DateTime.parseDateTime(endDate + " 23:59:59").toDateTimeString());
        List<LogWarning> result = warnQueryService.getLogInfo(logQuery);
        Map<Integer, WaterLoggingSet> colorMap = warnQueryService.getLogLevelInfo();
		int a = 0;
        // 兰伯特转经纬度
        for (LogWarning logWarning : result) {
            Double lon = 0.0;
            Double lat = 0.0;
            ArrayList<CEntity> cEntities = new ArrayList<CEntity>();
            if (logWarning.getWarnPos() != null) {
                String[] posArr = logWarning.getWarnPos().split("\\*");
                for (String pos : posArr) {
					System.out.println(a++);
                    try {
						if (pos == null || pos.equals("")) {
							continue;
						}
						CEntity cEntity = new CEntity();
						ArrayList<MyPoint> tempPos = new ArrayList<MyPoint>();
						String strColor = pos.split("#")[0];
						// 16进制颜色
						cEntity.setColor(strColor);
						cEntity.setWarnLevel(colorMap.get(Integer.parseInt(strColor)).getGradeType());
						String[] dotset = pos.split("#")[1].split(",");

						Integer index = 0;
						DmMapPoint[] points = new DmMapPoint[dotset.length];
						for (String strDot : dotset) {
							String[] dot = strDot.split(" ");
//							DmMapPoint dmMapPoint = transformService.LambertConvertToLonLat(Double.parseDouble(dot[0]), Double.parseDouble(dot[1]));
							MyPoint myPoint = new MyPoint(Double.parseDouble(dot[0]), Double.parseDouble(dot[1]));
							tempPos.add(myPoint);
							points[index] = new DmMapPoint(Double.parseDouble(dot[0]), Double.parseDouble(dot[1]));
							index++;
						}
						MapCommon dmMapCom = new MapCommon();
						int[] parts = new int[1];
						parts[0] = points.length;
						DmMapPoint dmdotCenter = getPolygonCenterPointOptimized(points, parts, 1);
						lon += dmdotCenter.x;
						lat += dmdotCenter.y;
						cEntity.setPosArr(tempPos);
						cEntities.add(cEntity);
					} catch (Exception e) {
                        System.err.println(e.getStackTrace());
                    }
                }
                lon = lon / posArr.length;
                lat = lat / posArr.length;
                logWarning.setEntites(cEntities);
                Date date = logWarning.getForecastTime();
                logWarning.setDate(new DateTime(date).toDateString());
                logWarning.setForecastTime(null);
                logWarning.setLon(lon);
                logWarning.setLat(lat);
                // 文件处理
            }
        }
        return result;
	}
	public DmMapPoint getPolygonCenterPointOptimized(DmMapPoint[] polygonPoints, int[] partCounts, int partNum) {
		// 参数校验（快速失败）
		if (polygonPoints == null || polygonPoints.length == 0 || partCounts == null || partNum <= 0) {
			throw new IllegalArgumentException("Invalid parameters");
		}

		// 1. 快速计算外包矩形（单次遍历）
		double minX = polygonPoints[0].x, maxX = minX;
		double minY = polygonPoints[0].y, maxY = minY;
		for (int i = 1; i < polygonPoints.length; i++) {
			double x = polygonPoints[i].x, y = polygonPoints[i].y;
			if (x < minX) minX = x;
			else if (x > maxX) maxX = x;
			if (y < minY) minY = y;
			else if (y > maxY) maxY = y;
		}

		// 2. 计算水平中线（使用位运算代替除法）
		final double centerY = (maxY + minY) * 0.5;
		final double epsilon = 1e-10;

		// 3. 预分配足够空间的数组（避免ArrayList扩容）
		double[] intersections = new double[polygonPoints.length]; // 最坏情况下每个边都可能相交
		int intersectCount = 0;

		// 4. 主计算逻辑（优化循环和条件判断）
		int pointIndex = 0;
		for (int part = 0; part < partNum; part++) {
			int partEnd = pointIndex + partCounts[part] - 1;

			for (int i = pointIndex; i < partEnd; i++) {
				DmMapPoint p1 = polygonPoints[i], p2 = polygonPoints[i+1];
				double y1 = p1.y, y2 = p2.y;

				// 4.1 快速判断是否可能相交
				if ((y1 > centerY) != (y2 > centerY)) {
					// 计算交点X坐标（减少重复计算）
					double dx = p2.x - p1.x;
					double dy = p2.y - p1.y;
					intersections[intersectCount++] = p1.x + (centerY - y1) * dx / dy;
				}
				// 4.2 处理顶点在水平线上的情况（使用短路判断优化）
				else if (Math.abs(y1 - centerY) < epsilon && i > pointIndex) {
					DmMapPoint prev = polygonPoints[i-1];
					DmMapPoint next = p2;
					// 使用叉积判断凸性（避免创建临时对象）
					double cross = (next.x - p1.x) * (prev.y - p1.y) - (prev.x - p1.x) * (next.y - p1.y);
					if (cross > epsilon) {
						intersections[intersectCount++] = p1.x;
					}
				}
			}
			pointIndex += partCounts[part];
		}

		// 5. 处理无交点情况（快速返回）
		if (intersectCount == 0) {
			return new DmMapPoint((minX + maxX) * 0.5, (minY + maxY) * 0.5);
		}

		// 6. 使用双轴快速排序（对实际有数据的部分排序）
		Arrays.sort(intersections, 0, intersectCount);

		// 7. 计算加权中心（使用循环展开优化）
		double totalWeight = 0, weightedSum = 0;
		for (int i = 0; i < intersectCount; i += 2) {
			double x1 = intersections[i], x2 = intersections[i+1];
			double length = x2 - x1;
			totalWeight += length;
			weightedSum += length * (x1 + x2);
		}

		// 8. 计算结果并限制边界（避免分支预测失败）
		double centerX = weightedSum / (totalWeight * 2);
		return new DmMapPoint(
				Math.max(minX, Math.min(maxX, centerX)),
				Math.max(minY, Math.min(maxY, centerY))
		);
	}


	@RequestMapping("/showDoc")
	@ResponseBody
	public String showDoc(HttpServletRequest request, Model model) throws IOException {
		String servicePath = "";
		String docPath = request.getParameter("docpath");
		if (docPath == null || docPath.equals("")) {
			return "";
		}
		String id = warnQueryService.getProductID(docPath);// 获取编号
		String urlpath ;
		if (operatingSystem.equals("Windows")){
			 urlpath = request.getSession().getServletContext().getRealPath("/") + "Temp\\logWarning\\";// 临时文件目录
		}else {
			 urlpath = request.getSession().getServletContext().getRealPath("/") + "Temp/logWarning/";// 临时文件目录
		}
		String path = request.getContextPath();
		String basePath = DbConfig.IP + path;
		FileUtil.mkDirs(urlpath);// 创建文件夹，生成多级目录
		FileUtil.ClearTempFiles(urlpath, 1000);// 清除缓存

		String fileName = docPath.split("\\\\")[docPath.split("\\\\").length - 1];// 文件名
		String doctype = fileName.split("\\.")[fileName.split("\\.").length - 1];// 文件类型
		if (doctype.contains("doc")) {
			//String localPath = urlpath + fileName;
			String pdfPath = urlpath + fileName.replace(doctype, "pdf");
			File pdfFile = new File(pdfPath);
			if (pdfFile.exists()) {
				if (operatingSystem.equals("Windows")){
					servicePath = "\\Temp\\logWarning\\" + fileName.replace(doctype, "pdf");
				}else {
					servicePath = "/Temp/logWarning/" + fileName.replace(doctype, "pdf");
				}
				servicePath = basePath+servicePath;
			} else {
				Map<String, Object> map = new HashMap<String, Object>();
				map.put("id", id);
				map.put("table_name", "base_product");
				map.put("collectionName", "pdf_file");
				map.put("advCode", DbConfig.advCode);
				byte[] data = ms.selectData(map);
				FileUtil.bytesToFile(data, pdfPath);
				// 下载doc文件
				if (data == null) {
					return "";
				}
				if (operatingSystem.equals("Windows")){
					servicePath = "\\Temp\\logWarning\\" + fileName.replace(doctype, "pdf");
				}else {
					servicePath = "/Temp/logWarning/" + fileName.replace(doctype, "pdf");
				}

				servicePath = basePath+servicePath;
			}
		}
		servicePath = servicePath.replace("\\", "/");
		return servicePath;
	}

	/**
	 * 获取气象台发布的预警信号
	 *
	 * @param request
	 * @param model
	 * @return
	 * @author dsq
	 * @date 2018年7月19日
	 */
	@RequestMapping("/showWarning")
	@ResponseBody
	public Object showWarning(HttpServletRequest request, Model model) {
		String startDate = request.getParameter("startDate");
		String endDate = request.getParameter("endDate");
		return warnQueryService.getWarningInfo(startDate, endDate, -1);// 查询时间段内的预警信息号
	}
}

/**
 * This class is used for 面实体排序
 *
 * @author dsq
 * @version 1.0, 2018年7月14日 下午4:42:35
 */
class SortByColor implements Comparator<Object> {
	public int compare(Object o1, Object o2) {
		CEntity entity1 = (CEntity) o1;
		CEntity entity2 = (CEntity) o2;
		if (Integer.parseInt(entity1.getColor()) > Integer.parseInt(entity2.getColor()))
			return 1;
		return -1;
	}
}
